package com.myapp.db.conn;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.apache.log4j.Logger;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.myapp.data.global.Instances;

public class ConnectionFactory1 {

	// 日志
	private Logger log = Logger.getLogger(ConnectionFactory1.class);

	private static ConnectionFactory1 connectionFactory = null;

	private SqlSessionFactory sqlSessionFactory = null;

	public static ConnectionFactory1 getInstance() {
		if (connectionFactory == null) {
			connectionFactory = new ConnectionFactory1();
		}
		return connectionFactory;
	}

	private ConnectionFactory1() {
		sqlSessionFactory = this.init(Instances.getAppConfigBean()
				.getCurrentPath()
				+ Instances.getAppConfigBean().getSqlMapConfig(), Instances
				.getAppConfigBean().getCurrentPath()
				+ Instances.getAppConfigBean().getPoolConfig());
	}

	/**
	 * 初始化数据库链接工程
	 * 
	 * @param sql_config
	 *            SQLMap配置文件
	 * @param pool_config
	 *            连接池配置文件
	 * 
	 * @return 返回连接工厂
	 */
	private SqlSessionFactory init(String sql_config, String pool_config) {
		SqlSessionFactory sqlSessionFactory = null;
		InputStream is = null;
		Reader reader = null;
		try {
			is = new FileInputStream(sql_config);
			reader = new InputStreamReader(is, "UTF-8");
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
			// 获取原配置的config
			Configuration configuration = sqlSessionFactory.getConfiguration();
			// 获取C3P0数据源
			DataSource dataSource = this.getDataSource(pool_config);
			// 重新配置环境变量
			Environment environment = new Environment("product",
					new JdbcTransactionFactory(), dataSource);
			configuration.setEnvironment(environment);
			sqlSessionFactory = new SqlSessionFactoryBuilder()
					.build(configuration);
		} catch (Exception e) {
			log.error("Init database connection Failure.", e);
			System.exit(1);
		} finally {
			try {
				if (reader != null) {
					reader.close();
					reader = null;
				}
			} catch (Exception e) {
			}

			try {
				if (is != null) {
					is.close();
					is = null;
				}
			} catch (Exception e) {
			}
		}
		return sqlSessionFactory;
	}

	private ComboPooledDataSource getDataSource(String configFile)
			throws Exception {
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		// 设置链接参数
		Properties prop = new Properties();
		InputStream is = null;
		Reader re = null;
		try {
			is = new FileInputStream(configFile);
			re = new InputStreamReader(is, "UTF-8");
			prop.load(re);
			// 初始化bean
			dataSource.setDriverClass(prop.getProperty("DriverClass"));
			dataSource.setJdbcUrl(prop.getProperty("JdbcUrl"));
			dataSource.setUser(prop.getProperty("User"));
			dataSource.setPassword(prop.getProperty("Password"));
			dataSource.setInitialPoolSize(Integer.parseInt(prop
					.getProperty("InitialPoolSize")));
			dataSource.setMaxPoolSize(Integer.parseInt(prop
					.getProperty("MaxPoolSize")));
			dataSource.setMinPoolSize(Integer.parseInt(prop
					.getProperty("MinPoolSize")));
			dataSource.setAcquireIncrement(Integer.parseInt(prop
					.getProperty("AcquireIncrement")));
			dataSource.setAutoCommitOnClose(Boolean.getBoolean(prop
					.getProperty("AutoCommitOnClose")));
			return dataSource;
		} finally {
			try {
				if (re != null) {
					re.close();
					re = null;
				}
			} catch (Exception e) {
			}

			try {
				if (is != null) {
					is.close();
					is = null;
				}
			} catch (Exception e) {
			}
		}
	}

	/**
	 * 获取数据库操作对象的session
	 * 
	 * @return SqlSession
	 */
	public SqlSession getDBConnection() {
		if (this.sqlSessionFactory != null) {
			return this.sqlSessionFactory.openSession(true);
		} else {
			throw new IllegalArgumentException("DBSessionFactory is null");
		}
	}

}
